package top.tupobi.zing.service.socket;

import com.google.gson.Gson;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import top.tupobi.zing.service.socket.listener.OnSocketListener;
import top.tupobi.zing.service.socket.packet.DataType;
import top.tupobi.zing.service.socket.packet.SocketPacket;

public class ClientSocketProcessor {
    private OnSocketListener mOnSocketListener;
    private Socket mSocket = null;
    private DataOutputStream mDataOutputStream = null;
    private DataInputStream mDataInputStream = null;
    private boolean mIsConnected;
    private ClientSocketReceiverThread mClientSocketReceiverThread;

    public void setOnSocketListener(OnSocketListener onSocketListener) {
        mOnSocketListener = onSocketListener;
    }

    public void connect(String ip, int port) {
        try {
            // 连接服务器，连接不上直接进异常，不会继续执行下面语句，是同步的
            mSocket = new Socket(ip, port);
//            mSocket = new Socket();
//            mSocket.connect(new InetSocketAddress(ip,port), HttpConfig.SOCKET_TIME_OUT);
//            mSocket.setSoTimeout(HttpConfig.SOCKET_TIME_OUT);
            if (!mSocket.getKeepAlive()) mSocket.setKeepAlive(true);//true，若长时间没有连接则断开
            if (!mSocket.getOOBInline()) mSocket.setOOBInline(true);//true,允许发送紧急数据，不做处理
            mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
            mDataInputStream = new DataInputStream(mSocket.getInputStream());
            System.out.println("~~~~~~~~连接成功~~~~~~~~!");
            mIsConnected = true;
            mClientSocketReceiverThread = new ClientSocketReceiverThread(mDataInputStream, mSocket);
            mClientSocketReceiverThread.setOnReceiveDataListener(new OnReceiveDataListener() {
                @Override
                public void onReceiveData(String data) {
                    mOnSocketListener.onReceiveData(data);
                }

                @Override
                public void onDisconnectedEOFException() {
                    System.out.println("异常关闭连接onDisconnectedEOFException");
                    mIsConnected = false;
                    mOnSocketListener.onConnectFail();
                }

                @Override
                public void onDisConnectedSocketException() {
                    System.out.println("异常关闭连接onDisConnectedSocketException");
                    mIsConnected = false;
                    mOnSocketListener.onConnectFail();
                }

                @Override
                public void onDisconnectedIOException() {
                    System.out.println("onDisconnectedIOException");
                    mIsConnected = false;
                    mOnSocketListener.onConnectFail();
                }

            });
            new Thread(mClientSocketReceiverThread).start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            mOnSocketListener.onUnknownHostError();
        } catch (IOException e) {
            e.printStackTrace();
            mOnSocketListener.onConnectFail();
        }
    }

    public void disConnectSocket() {
        if (mSocket != null && mDataInputStream != null && mDataOutputStream != null && isSocketConnected()) {
            try {
                //关闭socket的特殊包
                SocketPacket packet = SocketPacket.createPacket(DataType.DATA_TYPE_STOP_HEARTBEAT);
                sendData(new Gson().toJson(packet));
                mIsConnected = false;
                if (!mSocket.isClosed()) {
                    mSocket.shutdownInput();
                    mSocket.shutdownOutput();
                    mClientSocketReceiverThread.stopReceiveData();
                    mSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("客户端断开连接失败：IOException");
            }

        }
    }

    public void sendData(String data) {
        if (isSocketConnected()) {
            try {
                System.out.println("发送给服务端的数据data == " + data);
                mDataOutputStream.writeUTF(data);
                mDataOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("客户端发送数据失败：IOException");
            }
        } else {
            System.out.println("socket未连接，发送不了消息");
        }
    }

    public boolean isSocketConnected() {
        return mIsConnected && mSocket.isConnected();
    }

    public void reConnect(String ip, int port) {
        mIsConnected = false;
        connect(ip, port);
    }
}

